Spring 框架有兩個很重要的觀念,一個是 IoC,另一個則是 AOP,只是 AOP 大多整合進應用中,開發人員直接撰寫 AOP 的機會越來越少,很多開發人員甚至都忘了還有這種功能
AOP 的基本概念就是可以攔截指定的方法並且增強方法的功能,且無需修改到主要的業務代碼,使業務與非業務處理邏輯分離
例如 @Transactional
標註,只要元件的方法上增加 @Transactional
標註,Spring 會自動在方法中進行 Open、Commit,並且在業務處理失敗時,執行 Rollback。
另一個常見的應用是 log,使用 AOP 可以在不更動原程式的情況下在執行前後加上 log 紀錄
在 Spring AOP 中 Advisor(增強器) 的作用就是找到切入點對應的方法,並在定義的時機執行 Advice(增強方法),還記得 Day15 最後提到的 .advisors()
嗎?這正是要放入 Advisor 的地方,Spring AI 提供了 RequestResponseAdvisor
介面,只要實作就能在 ChatModel 執行 call()
或是 stream()
的前後調用 Advisor,目前 Spring AI 提供的實作類別有以下四個
今天先來實作短期記憶,凱文大叔將昨天的 Service 進行改寫,原本手動加入 InMemoryChatMemory 以及取得歷史訊息的部分不用自己動手了
@RequiredArgsConstructor
@Service
public class ChatService {
private final ChatClient chatClient;
private final ChatMemory chatMemory = new InMemoryChatMemory();
public String chat(String chatId, String userMessage) {
return this.chatClient.prompt()
.advisors(new MessageChatMemoryAdvisor(chatMemory, chatId, 30))
.user(userMessage)
.call().content()
}
}
MessageChatMemoryAdvisor
與 PromptChatMemoryAdvisor
兩者效果基本差不多,大家可以自行測試結果是否有差異,放入的參數分別如下chatMemory
:用來存對話訊息的 ChatMemorychatId
:區分對話的代號30
:送給 AI 的最近歷史聊天數量
為了驗證結果,特別加入log,分別在發送訊息前以及收到訊息後印出
@RequiredArgsConstructor
@Service
@Slf4j
public class ChatService {
private final ChatClient chatClient;
private final ChatMemory chatMemory = new InMemoryChatMemory();
public String chat(String chatId, String userMessage) {
log.info("Chat ID:{} User Message:{}",chatId,userMessage); //Request Message
String assistantMessage = this.chatClient.prompt()
.advisors(new MessageChatMemoryAdvisor(chatMemory, chatId, 30))
.user(userMessage)
.call().content();
log.info("Chat ID:{} Assistant Message:{}",chatId,assistantMessage); //Response Message
return assistantMessage;
}
}
可以看出效果跟昨天一樣,MessageChatMemoryAdvisor 與 PromptChatMemoryAdvisor 只差在歷史訊息送出的方式,大家可以挑一種喜歡的來使用即可
今天學到了甚麼?
程式看起來與昨天差別不大,不過
.advisors()
是可放入多個 Advisor 程式的,除了 Spring AI 提供的以外,開發人員也可以自行實作RequestResponseAdvisor
,明天我們就將 log 改寫成 Advisor 讓大家熟悉Advisor 鏈的寫法
程式碼下載: https://github.com/kevintsai1202/SpringBoot-AI-Day19.git
凱文大叔使用 Java 開發程式超過 20 年,對於 Java 生態非常熟悉,曾使用反射機制開發 ETL 框架,對 Spring 背後的原理非常清楚,目前以 Spring Boot 作為後端開發框架,前端使用 React 搭配 Ant Design
下班之餘在 Amazing Talker 擔任程式語言講師,並獲得學員的一致好評
最近剛成立一個粉絲專頁-凱文大叔教你寫程式 歡迎大家多追蹤,我會不定期分享實用的知識以及程式開發技巧
想討論 Spring 的 Java 開發人員可以加入 FB 討論區 Spring Boot Developer Taiwan
我是凱文大叔,歡迎一起加入學習程式的行列